package com.hzhc.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzhc.entity.*;
import com.hzhc.mapper.CntrStockPlanMapper;
import com.hzhc.mapper.YwOrderCntrMapper;
import com.hzhc.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzhc.utils.ResultUtil;
import com.hzhc.vo.CntrStockPlanVo;
import com.hzhc.vo.DeclareCarVo;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 堆存计划 服务实现类
 * </p>
 *
 * @author 功不唐捐
 * @since 2025-04-10
 */
@Service
@RequiredArgsConstructor
public class CntrStockPlanServiceImpl extends ServiceImpl<CntrStockPlanMapper, CntrStockPlan> implements CntrStockPlanService {
    private final DeclareCarService declareCarService;
    private final CntrInfoService cntrInfoService;
    private final CntrYardService cntrYardService;
    private final YwOrderCntrService ywOrderCntrService;
    private final YwOrderCntrMapper ywOrderCntrMapper;
    String[] peiarr = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G" };
    Integer startpainum = 1;// 开始排数
    Integer endpainum = 7;// 结束排数
    Integer startbeinum = 2;// 开始贝数
    Integer endbeinum = 38;// 结束贝数
    Integer cntrxh = 40;// 箱型号20尺或40尺
    String mrbay = "1A";
    Integer LEVELNUM = 2;// 层高
    Integer SEQNUMCL = 1;// 策略的值
    Boolean USEUP = false;// 是否用完备位


    @Override
    public String getBayCalc(DeclareCarVo vo) {
        String calcBay = "";
        String cntrsize = vo.getCntrSizeA();// 箱尺寸

        if (StrUtil.isNotBlank(cntrsize) && cntrsize.startsWith("2")) {
            cntrxh = 20;
        } else {
            cntrxh = 40;
        }
        vo.setCntrxh(cntrxh);
        // 空重
        String eFflag = "F";
        if ("E".equals(vo.getEfFlagA())) {
            eFflag = "E";
        }
        //处理到站 品名为空的情况
        if(StrUtil.isBlank(vo.getDestinationA())){
            vo.setDestinationA("无");
        }
        if(StrUtil.isBlank(vo.getHwnameA())){
            vo.setHwnameA("无");
        }
        // 查询出来堆场的全部在场箱用来判断贝位是否被占用
        List<CntrInfo> zccntrList = cntrInfoService.getOnAreaCntrList();
        //处理在场箱到站 品名为空时给无
        for (CntrInfo cntrInfo :zccntrList){
            if(StrUtil.isBlank(cntrInfo.getEndPort())){
                cntrInfo.setEndPort("无");
            }
            if(StrUtil.isBlank(cntrInfo.getGoods())){
                cntrInfo.setGoods("无");
            }
        }
        // 查询在场,但是未理货的全部,用来判断贝位是否被占用
        List<DeclareCar> carList = declareCarService.getUnfinishedDeclareCarList(null);
        YwOrderCntr oneCntr =  ywOrderCntrMapper.selectOne(new QueryWrapper<YwOrderCntr>()
                .eq("order_no",vo.getOrderNo())
                .eq("cntr_no",vo.getCntrA())
                .eq("disable",0));
        //卡口进卡2个箱子的情况下，第一个箱子的计划贝位已生成时将该箱模拟在场箱集合中模拟该贝位已使用。
        if(StrUtil.isNotBlank(vo.getJhBaya())){
            CntrInfo mnCntr = new CntrInfo();
            mnCntr.setCntrNo(vo.getCntrA());
            mnCntr.setBay(vo.getJhBaya());
            mnCntr.setEndPort(oneCntr.getDestination());
            mnCntr.setGoods(oneCntr.getGoodsName());
            zccntrList.add(mnCntr);
        }
        // 卡口进来临时贝位处理
        // 重新处理在场位理货的箱子
        for (DeclareCar carcntr : carList) {
            if (StrUtil.isNotBlank(carcntr.getCntrA()) && StrUtil.isNotBlank(carcntr.getJhBaya())) {
                CntrInfo cntr1 = cntrInfoService.getByCntrNo(carcntr.getCntrA());
                YwOrderCntr ywcntr = ywOrderCntrService.getCntrByorderNoCntrNo(vo.getOrderNo(), carcntr.getCntrA());
                if (cntr1 == null) {
                    // System.out.println(cntr1.getCntrNo());
                    cntr1 = new CntrInfo();
                    cntr1.setCntrNo(carcntr.getCntrA());
                    cntr1.setBay(carcntr.getJhBaya());
                    if (ywcntr != null) {
                        cntr1.setEndPort(StrUtil.isNotBlank(ywcntr.getDestination()) ? ywcntr.getDestination():"无");
                        cntr1.setGoods(StrUtil.isNotBlank(ywcntr.getGoodsName()) ? ywcntr.getGoodsName():"无");
                    } else {
                        cntr1.setEndPort("无");
                        cntr1.setGoods("无");
                    }
                    zccntrList.add(cntr1);
                } else if (cntr1.getStatus() == 1) {
                    cntr1.setBay(carcntr.getJhBaya());
                    if (ywcntr != null) {
                        cntr1.setEndPort(StrUtil.isNotBlank(ywcntr.getDestination()) ? ywcntr.getDestination():"无");
                        cntr1.setGoods(StrUtil.isNotBlank(ywcntr.getGoodsName()) ? ywcntr.getGoodsName():"无");
                    } else {
                        cntr1.setEndPort("无");
                        cntr1.setGoods("无");
                    }
                    zccntrList.add(cntr1);
                }
            }
            if (StrUtil.isNotBlank(carcntr.getCntrB()) && StrUtil.isNotBlank(carcntr.getJhBayb())) {
                CntrInfo cntr1 = cntrInfoService.getByCntrNo(carcntr.getCntrB());
                //修改成kcyworder
                YwOrderCntr  ywcntr = ywOrderCntrService.getCntrByorderNoCntrNo(vo.getOrderNo(), carcntr.getCntrB());
                if (cntr1 == null) {
                    // System.out.println(cntr1.getCntrNo());
                    cntr1 = new CntrInfo();
                    cntr1.setCntrNo(carcntr.getCntrB());
                    cntr1.setBay(carcntr.getJhBayb());
                    if (ywcntr != null) {
                        cntr1.setEndPort(StrUtil.isNotBlank(ywcntr.getDestination()) ? ywcntr.getDestination():"无");
                        cntr1.setGoods(StrUtil.isNotBlank(ywcntr.getGoodsName()) ? ywcntr.getGoodsName():"无");
                    } else {
                        cntr1.setEndPort("无");
                        cntr1.setGoods("无");
                    }
                    zccntrList.add(cntr1);
                } else if (cntr1.getStatus() == 1) {
                    cntr1.setBay(carcntr.getJhBayb());
                    if (ywcntr != null) {
                        cntr1.setEndPort(StrUtil.isNotBlank(ywcntr.getDestination()) ? ywcntr.getDestination():"无");
                        cntr1.setGoods(StrUtil.isNotBlank(ywcntr.getGoodsName()) ? ywcntr.getGoodsName():"无");
                    } else {
                        cntr1.setEndPort("无");
                        cntr1.setGoods("无");
                    }
                    zccntrList.add(cntr1);
                }
            }
        }
//        for (CntrInfo cntr : zccntrList) {
//            // 处理目的港的问题
//            // 重新设置目的港,以最新导入的装船计划里箱目的为主
//            String cntrno = cntr.getCntrNo();
//            List<YwOrderCntr> list = ywOrderCntrMapper.getUnfinishedCntrList();
//            for (YwOrderCntr ycntr : list) {
//                if (cntrno.equals(ycntr.getCntrNo())) {
//                    if (StrUtil.isNotBlank(ycntr.getDestination())) {
//                        cntr.setEndPort(StrUtil.isNotBlank(ycntr.getDestination()) ? ycntr.getDestination():"无");
//                        cntr.setGoods(StrUtil.isNotBlank(ycntr.getGoodsName()) ? ycntr.getGoodsName():"无");
//                    }
//                }
//            }
//        }
        //获取二程船
        YwOrderCntr ywOrderCntr =  ywOrderCntrMapper.selectOne(new QueryWrapper<YwOrderCntr>()
                .eq("order_no",vo.getOrderNo())
                .eq("cntr_no",vo.getCntrNo())
                .eq("disable",0));
        if(ywOrderCntr != null){
            vo.setHwnameA(StrUtil.isNotBlank(ywOrderCntr.getGoodsName()) ? ywOrderCntr.getGoodsName():"无");
        }
        // 多条策略处理
        List<CntrStockPlan> cntrStockPlans = getListByOrderNo(vo.getOrderNo(), cntrxh, eFflag);
        for (CntrStockPlan cntrstockplan : cntrStockPlans) {
            if (cntrstockplan != null) {
                // 控制参数从这里获取初始化作用
                mrbay = cntrstockplan.getArea();
                startbeinum = cntrstockplan.getBayStart();// 起始贝
                endbeinum = cntrstockplan.getBayEnd();// 终止贝
                startpainum = cntrstockplan.getRowStart();// 起始排
                endpainum = cntrstockplan.getRowEnd();// 终止排
                LEVELNUM = cntrstockplan.getBayHight();// 层高限制
                SEQNUMCL = cntrstockplan.getStrategyField(); //策略值
            }
            // 计算策略可以场地内存放多少箱子数量
            int zsnum = 0;
            int deffpai = endpainum - startpainum;
            for (int i = startbeinum; i <= endbeinum; i++) {
                if (cntrxh == 40) {
                    if (i % 2 == 0 && i % 4 != 0) {
                        zsnum += (deffpai + 1) * LEVELNUM;
                    }
                } else {
                    if (i % 2 != 0) {
                        zsnum += (deffpai + 1) * LEVELNUM;
                    }
                }
            }

            // System.out.println("zsnum===" + zsnum);
            calcBay = getDefaultBay(cntrstockplan);// "1A-02-1-1";// 默认值
            int j = 0;
            while (isApplyBay(calcBay, vo, zccntrList, carList, cntrxh)) {
                j++;
                if (j == zsnum) {
                    USEUP = true;
                    break;
                }
                calcBay = getNextOnebay(calcBay);
            }
            System.out.println("j===" + j);
            // 是否用完备位
            if (USEUP) {
                j = 0;
                USEUP = false;
                // return calcBay;
            } else {
                return calcBay;
            }
        }
        //
        // CntrStockPlan cntrstockplan = getObjByOrderNo(vo.getOrderNo(), cntrxh,
        // eFflag, SEQNUMCL);
        // 用完贝位返回空的计划贝位 页面进行判断
        if(!USEUP){
            return "";
        }
        return calcBay;
    }

    @Override
    public ResultUtil<T> addYardPlan(CntrStockPlan plan) {
        plan.setCreateTime(LocalDateTime.now());
        boolean b = save(plan);
        if(plan.getValid()==0){
            List<CntrStockPlan> cntrStockPlans = baseMapper.selectList(new QueryWrapper<CntrStockPlan>().eq("disable", 0)
                    .eq("order_no", plan.getOrderNo()).eq("cntr_size", plan.getCntrSize()).ne("id",plan.getId()));
            if(cntrStockPlans.size()>0){
                for (CntrStockPlan stockPlan : cntrStockPlans) {
                    stockPlan.setValid(1);
                }
                updateBatchById(cntrStockPlans);
            }
        }
        if(b){
            return ResultUtil.ok();
        }
        return ResultUtil.fail();
    }

    @Override
    public List<CntrStockPlanVo> getList(CntrStockPlanVo vo, Page<CntrStockPlanVo> page) {
        List<CntrStockPlanVo> cntrStockPlans = baseMapper.selectListPlan(vo);
        return cntrStockPlans;
    }

    @Override
    public ResultUtil<T> changeValid(CntrStockPlan plan) {
        CntrStockPlan cntrStockPlan = baseMapper.selectById(plan.getId());
        cntrStockPlan.setValid(plan.getValid());
        if(plan.getValid()==0){
            List<CntrStockPlan> cntrStockPlans = baseMapper.selectList(new QueryWrapper<CntrStockPlan>().eq("disable", 0)
                    .eq("order_no", plan.getOrderNo()).eq("cntr_size", plan.getCntrSize()).ne("id",cntrStockPlan.getId()));
            if(cntrStockPlans.size()>0){
                for (CntrStockPlan stockPlan : cntrStockPlans) {
                    stockPlan.setValid(1);
                }
                updateBatchById(cntrStockPlans);
            }
        }
        boolean b = updateById(cntrStockPlan);
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    public List<CntrStockPlan> getListByOrderNo(String orderNo, Integer cntrxh, String eFflag) {
        // TODO Auto-generated method stub
        QueryWrapper<CntrStockPlan> queryWrapper = new QueryWrapper<CntrStockPlan>();
        queryWrapper.eq("disable", false);
        queryWrapper.eq("order_no", orderNo);
        queryWrapper.eq("valid", 0);
        queryWrapper.eq("ef_flag", eFflag);
        queryWrapper.like("cntr_size", cntrxh + "%");
        queryWrapper.orderByAsc("id");
        List<CntrStockPlan> list = baseMapper.selectList(queryWrapper);
        return list;
    }

    private boolean isApplyBay(String calcBay, DeclareCarVo vo, List<CntrInfo> zccntrList, List<DeclareCar> carList,
                               Integer cntrxh) {

        if (zccntrList.size() == 0) {
            return false;
        }
        String[] arr = calcBay.split("-");
        Integer bnum = Integer.valueOf(arr[1]);
        Integer cghtnum = Integer.valueOf(arr[3]);

        for (CntrInfo cntr : zccntrList) {
            String cntrbay = cntr.getBay();
            if (cntrbay.equals(calcBay)) {
                return true;
            }
            // 判断20尺 40尺不能堆叠
            String[] cntrbayarr = cntrbay.split("-");
            String cntrbaypai = cntrbayarr[0] + "-" + cntrbayarr[1] + "-" + cntrbayarr[2];

            // String bjp = arr[0] + "-" + arr[1] + "-" + arr[2];
            if (cntrxh == 40) {
                int prebnum = bnum - 1;
                int sufbnum = bnum + 1;

                String prebjp = arr[0] + "-" + prebnum + "-" + arr[2];
                String sufbjp = arr[0] + "-" + sufbnum + "-" + arr[2];
                if (sufbnum < 10) {
                    prebjp = arr[0] + "-0" + prebnum + "-" + arr[2];
                    sufbjp = arr[0] + "-0" + sufbnum + "-" + arr[2];
                }
                if (cntrbaypai.equals(prebjp) || cntrbaypai.equals(sufbjp)) {
                    return true;
                }
            }
            if (cntrxh == 20) {
                int sufbnum = bnum + 1;
                if (sufbnum % 4 == 0) {
                    sufbnum = bnum - 1;
                }
                String sufbjp = arr[0] + "-" + sufbnum + "-" + arr[2];
                if (sufbnum < 10) {
                    sufbjp = arr[0] + "-0" + sufbnum + "-" + arr[2];
                }
                if (cntrbaypai.contentEquals(sufbjp)) {
                    return true;
                }
            }

        }
        // 在贝位没有被占用情况下第一层就是可以堆放的
        if (cghtnum == 1) {
            return false;
        }
        // 判断未理货的数据是否有已分配的贝位
        // List<DeclareCar> carList
        // 判断目的港一样往上堆放
        for (CntrInfo cntr : zccntrList) {
            String calcBaypai = arr[0] + "-" + arr[1] + "-" + arr[2];
            String zcbay = cntr.getBay();
            if (StrUtil.isNotBlank(zcbay)) {
                String[] zcbayarr = zcbay.split("-");
                String zcbaypai = zcbayarr[0] + "-" + zcbayarr[1] + "-" + zcbayarr[2];
                if(SEQNUMCL == 1){
                    if (calcBaypai.equals(zcbaypai) && cntr.getEndPort().equals(vo.getDestinationA())) {
                        return false;
                    }
                }else if(SEQNUMCL == 2){
                    // 判断品名一样往上堆放
                    if (calcBaypai.equals(zcbaypai) && StrUtil.isNotBlank(cntr.getGoods()) && cntr.getGoods().equals(vo.getHwnameA())) {
                        return false;
                    }
                }else if(SEQNUMCL == 3){
                    // 判断重量一样往上堆放
                    if (calcBaypai.equals(zcbaypai) && cntr.getWeightPred()!=null && cntr.getWeightPred().equals(vo.getJkWeight())) {
                        return false;
                    }
                }else{
                    if (calcBaypai.equals(zcbaypai)){
                        return false;
                    }
                }
            }
        }
        // 最后一个贝没有满足条件就终止
        // 判断是最后一个箱子如果是最后一个箱子就要调整下一个策略
//		String zhyg = "";
//		if (endbeinum < 10) {
//			zhyg = mrbay + "-0" + endbeinum + "-" + endpainum + "-" + LEVELNUM;
//		} else {
//			zhyg = mrbay + "-" + endbeinum + "-" + endpainum + "-" + LEVELNUM;
//		}
//		if (calcBay.equals(zhyg)) {
//			// System.out.println("调下一个。。。。");
//			SEQNUMCL++;
//			USEUP = true;
//			return false;
//		}
        return true;
    }

    /**
     * 生产默认起始贝
     *
     * @param cntrstockplan
     * @return
     */
    private String getDefaultBay(CntrStockPlan cntrstockplan) {
        // TODO Auto-generated method stub
        // String nextbnum = "1A-02-1-1";
        if (cntrstockplan != null) {
            // 控制参数从这里获取
            mrbay = cntrstockplan.getArea();
            startbeinum = cntrstockplan.getBayStart();// 起始贝
            endbeinum = cntrstockplan.getBayEnd();// 终止贝
            startpainum = cntrstockplan.getRowStart();// 起始排
            endpainum = cntrstockplan.getRowEnd();// 终止排
            LEVELNUM = cntrstockplan.getBayHight();// 层高限制
        } else {
            // 获取区域第一级
            List<CntrYard> areaList = cntrYardService.selectCntrArea();
            for (CntrYard cntrYard : areaList) {
                if ("1A".equals(cntrYard.getArea())) {// 没有计划就默认在1A区域堆放
                    // 开始排数
                    if (StrUtil.isNotBlank(cntrYard.getStartRow())) {
                        startpainum = Integer.valueOf(cntrYard.getStartRow());
                    }
                    // 结束排数
                    if (StrUtil.isNotBlank(cntrYard.getEndRow())) {
                        endpainum = Integer.valueOf(cntrYard.getEndRow());
                    }
                    Integer sartBay = Integer.valueOf(cntrYard.getStartBay());
                    Integer endBay = Integer.valueOf(cntrYard.getEndBay());
                    if (40 == cntrxh) {// 40尺箱子
                        if ((sartBay + 1) % 4 == 0) {
                            startbeinum = sartBay + 3;
                        } else {
                            startbeinum = sartBay + 1;
                        }
                        if ((endBay - 1) % 4 == 0) {
                            endbeinum = endBay - 3;
                        } else {
                            endbeinum = endBay - 1;
                        }
                    } else {
                        startbeinum = sartBay;// 开始贝数
                        endbeinum = endBay;// 结束贝数
                    }
                }
            }
        }
        if (startbeinum < 10) {
            if(startpainum<10){
                return mrbay + "-0" + startbeinum + "-0" + peiarr[startpainum - 1] + "-1";
            }else{
                return mrbay + "-0" + startbeinum + "-" + peiarr[startpainum - 1] + "-1";
            }
        } else {
            if(startpainum<10){
                return mrbay + "-" + startbeinum + "-0" + peiarr[startpainum - 1] + "-1";
            }else{
                return mrbay + "-" + startbeinum + "-" + peiarr[startpainum - 1] + "-1";
            }
        }
        // return nextbnum;
    }

    /**
     * *得到下一个贝位如1B-02-B-2
     *
//     * @param fricntr
//     * @param nextbnum
//     * @param vo
//     * @param isNextPai
     * @return
     */
    private String getNextOnebay(String bay) {
        // String nextbnum
        String[] nextbnums = bay.split("-");
        // 层高
        String startNum="";
        String endNum="";
        if(startbeinum<10){
            startNum= "0"+startbeinum;
        }else{
            startNum=startbeinum+"";
        }
        if(endbeinum<10){
            endNum= "0"+endbeinum;
        }else{
            endNum=endbeinum+"";
        }

        Integer highnum = Integer.valueOf(nextbnums[3]);
        String beistr = nextbnums[1];// 贝数
        String paistr = nextbnums[2];// 排数
        String nextBeinum = getNextbernum(beistr, startbeinum, endbeinum, cntrxh);
        String nextpainum = getNextPaiNum(paistr, peiarr, startpainum, endpainum);
        if (beistr.equals(startNum + "") && nextpainum.equals(peiarr[startpainum - 1])
                && paistr.equals(peiarr[endpainum - 1])) {
            bay = nextbnums[0] + "-" + nextBeinum + "-" + nextpainum + "-1";
        } else if (Integer.valueOf(paistr).equals(Integer.valueOf(peiarr[endpainum - 1]))) {

            if (highnum < LEVELNUM) {
                bay = nextbnums[0] + "-" + beistr + "-" + paistr + "-" + (highnum + 1);
            } else {
                bay = nextbnums[0] + "-" + nextBeinum + "-" + nextpainum + "-1";
            }

        } else {
            if (highnum < LEVELNUM) {
                bay = nextbnums[0] + "-" + beistr + "-" + paistr + "-" + (highnum + 1);
            } else {
                bay = nextbnums[0] + "-" + beistr + "-" + nextpainum + "-1";
            }
        }

        return bay;
    }

    /**
     * *得到下一列
     *
     * @param beistr
     * @param startbeinum
     * @param endbeinum
     * @param cntrxh
     * @return
     */
    private String getNextbernum(String beistr, Integer startbeinum, Integer endbeinum, Integer cntrxh) {
        if (StrUtil.isBlank(beistr)) {
            return startbeinum + "";
        }
        int beiNum = Integer.valueOf(beistr);
        if (beiNum == endbeinum) {
            if (beiNum < 10) {
                return "0" + beiNum;
            }
            return beiNum + "";
        }
        if (cntrxh == 40) {
            beiNum = beiNum + 4;
        } else {
            beiNum = beiNum + 2;
        }
        if (beiNum < 10) {
            return "0" + beiNum;
        }
        return beiNum + "";
    }

    /**
     * *得到下一排
     *
     * @param paistr
     * @param peiarr
     * @param startpainum
     * @param endpainum
     * @return
     */
    private String getNextPaiNum(String paistr, String[] peiarr, Integer startpainum, Integer endpainum) {
        String ret = peiarr[0];
//        if (startpainum >= 1) {
//            ret = peiarr[startpainum - 1];
//        }
        if (StrUtil.isBlank(paistr)) {
            return ret;
        }
        for (int i = (startpainum - 1); i < endpainum; i++) {
            if (i == (endpainum - 1)) {
                if (Integer.valueOf(peiarr[startpainum -1 ]) < 10) {
                    return "0" + peiarr[startpainum - 1];
                }else{
                    return peiarr[startpainum - 1];
                }
            }
            // System.out.println(paistr + "========" + i + "===" + peiarr[i]);
            if (Integer.valueOf(peiarr[i]).equals(Integer.valueOf(paistr))) {
                // System.out.println("========" + i);
                if (Integer.valueOf(peiarr[i + 1]) < 10) {
                    return "0" + peiarr[i + 1];
                }
            }
        }
        if (Integer.valueOf(ret) < 10) {
            return "0" + ret;
        }
        return ret;
    }

}
